<?php

namespace App\Console\Commands;

use App\Models\MembershipCode;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;

class GenerateMembershipCodesCommand extends Command
{
    /**
     * 命令名称
     *
     * @var string
     */
    protected $signature = 'membership:generate-codes
                            {type : 会员类型 (day, month, year, permanent)}
                            {count=10 : 生成数量 (默认10个)}
                            {--output=membership_codes_ : 输出文件名}
                            {--no-expires : 设置兑换码永不过期}';

    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '批量生成会员兑换码并输出到文本文件';

    /**
     * 执行命令
     */
    public function handle()
    {
        $type = $this->argument('type');
        $count = (int)$this->argument('count');
        $outputFile = $this->option('output');
        $noExpires = $this->option('no-expires');

        // 验证会员类型
        if (!array_key_exists($type, MembershipCode::$membershipTypes)) {
            $this->error('无效的会员类型，可用类型: day, month, year, permanent');
            return 1;
        }

        // 验证生成数量
        if ($count < 1 || $count > 100000) {
            $this->error('生成数量必须在1-100000之间');
            return 1;
        }

        // 确保输出路径存在
        $outputFile .= MembershipCode::$membershipTypes[$type]['name'].date('_YmdHis_').uniqid().'.txt';
        $outputPath = storage_path('membership_codes/'.$outputFile);
        $directory = dirname($outputPath);
        if (!File::exists($directory)) {
            File::makeDirectory($directory, 0755, true);
        }

        $this->info('开始生成 ' . $count . ' 个' . MembershipCode::$membershipTypes[$type]['name'] . '兑换码...');

        // 生成兑换码
        $codes = [];
        $bar = $this->output->createProgressBar($count);
        $bar->start();

        for ($i = 0; $i < $count; $i++) {
            // 如果设置了永不过期，则传入null
            $expiresAt = $noExpires ? null : null; // 默认永不过期

            $code = MembershipCode::generateCode($type, $expiresAt);
            $codes[] = [
                'code' => $code->code,
                'type' => $code->getTypeName(),
                'duration' => $code->type === 'permanent' ? '永久' : $code->duration . '天',
                'expires' => $code->expires_at ? $code->expires_at->format('Y-m-d H:i:s') : '永不过期'
            ];

            $bar->advance();
        }

        $bar->finish();
        $this->line('');

        // 写入文件
        $content = "会员兑换码列表 (生成时间: " . Carbon::now()->format('Y-m-d H:i:s') . ")\n";
        $content .= "===========================================\n";
        $content .= sprintf("%-20s %-10s %-10s %-20s\n", '兑换码', '类型', '有效期', '过期时间');
        $content .= "-------------------------------------------\n";

        $output = [];
        foreach ($codes as $code) {
            $output[] = $code['code'];
            $content .= sprintf("%-20s %-10s %-10s %-20s\n",
                $code['code'],
                $code['type'],
                $code['duration'],
                $code['expires']
            );
        }

        // 添加统计信息
        $typeName = MembershipCode::$membershipTypes[$type]['name'];
        $content .= "\n总计: {$count} 个{$typeName}会员兑换码";

        // 使用UTF-8编码写入文件，添加BOM标记
        $bom = chr(239) . chr(187) . chr(191); // UTF-8 BOM
        File::put($outputPath, $bom . implode("\n", $output));

        $this->info('成功生成 ' . $count . ' 个兑换码，已保存到: ' . $outputPath);
        return 0;
    }
}
